#ifndef IMAGE_NETWORK_READER_H_
#define IMAGE_NETWORK_READER_H_


#include <dirent.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>

#include <iostream>
#include <string>
#include <vector>
#include <thread>
#include <algorithm>  

#include "atlas_videocapture.h"
#include "dvpp_process.h"
#include "thread_safe_queue.h"
#include "utils.h"

using namespace std;



class ImageNetworkReader : public AtlasVideoCapBase {

public:
    // 跟踪当前网络网络连接的状态
    enum NetworkReaderStatus {
        READER_ERROR  = -1,
        READER_UNINIT = 0,
        READER_READY  = 1,
        READER_START  = 2,
        READER_FINISHED = 3
    };

    /**
     * @brief VideoDecode constructor
     */
    ImageNetworkReader(const std::string& protocol, int port, aclrtContext context = nullptr);

    /**
     * @brief VideoDecode destructor
     */
    ~ImageNetworkReader();

    static void FrameReadThreadFunction(void* readerSelf); 

    bool IsOpened();

    AtlasError Open();

    void SetStatus(NetworkReaderStatus status) { status_ = status; }
    NetworkReaderStatus GetStatus() { return status_; }

    AtlasError Set(StreamProperty key, uint32_t value) { return ATLAS_OK; }
    uint32_t Get(StreamProperty key);

    AtlasError SetAclContext();

    Result ReceiveDataProcess(unsigned char* buf);
    Result JpegImageDataProcess(shared_ptr<UdpFrame> &frame, unsigned char data[]);
    Result CreateInputImageData(const shared_ptr<uchar> buf, int bufSize, int id);
    void ProcessDecodedImage(shared_ptr<ImageData> frameData);


    AtlasError Read(ImageData& frame);

    AtlasError Close();

    void DestroyResource();
    bool IsStop() { return isStop_; }

private:
    AtlasError InitResource();
    AtlasError InitUdpSocket();
    AtlasError InitTcpSocket();
    void TcpNetworkRead(ImageNetworkReader* thisPtr);
    void UdpNetworkRead(ImageNetworkReader* thisPtr);
    AtlasError FrameImageEnQueue(shared_ptr<ImageData> frameData);
    shared_ptr<ImageData> FrameImageOutQueue(bool noWait = false);
    void StartFrameReader();
    int color_cycle();

private:
    aclrtContext context_;
    aclrtStream stream_;
    aclrtRunMode runMode_;

    NetworkReaderStatus status_;
    std::string protocolName_;
    int port_;
    thread readerThread_;

    int imageWidth_;
    int imageHeight_;

    int image_id = 0;
    int pre_image_seq = -1;
    int index_x, index_y;
    cv::Mat ImageMat;
    int networkSocket_;
    int color; // r:0, g:1, b:2

    shared_ptr<uchar> jpegImageBuffer_;
    int jpegImageBufferSize_;
    DvppProcess dvpp_;

    ThreadSafeQueue<shared_ptr<ImageData>> frameImageQueue_;
    
    bool isStop_;
    bool isReleased_;
};

#endif /* IMAGE_NETWORK_READER_H_ */
